// Learn TypeScript:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html
import { gcfg } from "../../../gcfg";
const { ccclass, property } = cc._decorator;


/**
 * 加载视频状态
 */
enum LoadRewardState {
    none,           //初始空状态
    loading,        //加载中
    load_comlepte,  //加载完成
    load_error      //加载失败
}

/**
 * 加载视频状态记录
 */
enum LoadInterstitialState {
    none,           //初始空状态
    loading,        //加载中
    load_comlepte,  //加载完成
    load_error      //加载失败
}

/**
 * Facebook 广告管理
 * 使用静态方法调用方式，结果以回调方式返回，目前只维护一个视频与插屏实例，（创建太多会出错）
 * 使用方法：1. 在游戏启动后开始调用load开头的方法（需要视频则调用加载视频方法，需要插屏则调用插屏加载）
 *			 2. 在需要判断视频/插屏是否缓存完成，可以调用isComplete开头的方法去做判断
 *           3. show开头的方法是显示相关的广告调用
 *
 *	其它注意事项：应该在多个节点添加Load开头的方法用于缓存广告，避免在用于没有广告使用。如：游戏开始前，游戏结束后，暂停，（视频播放后不需要手动调用，已在内部调用，load方法重复调用已经做了相关处理）
 */
@ccclass
export default class AdsManager {
   
    //缓存视频实例
    private static preloadedRewardedVideo: any = null;
    //加载视频状态记录变量
    private static loadingRewardedVideoState: LoadRewardState = LoadRewardState.none;

    
	//缓存插屏实例
    private static preloadedInterstitial: any = null;
	//插屏实例状态
    private static loadingInterstitialState: LoadInterstitialState = LoadInterstitialState.none;

    //上次显示时间
    private static LastShowAdsTime: number = 0;
    //插屏广告调用并不需要按钮触发，可能会与视频间隔太短时间，添加这个变量用于插屏广告之间显示时间间隔控制，激励广告不受此时间间隔影响
    private static AdsCDTime: number = 30;

    /**
     *  获取相应版本的广告ID
     */
    private static getRewardedPlacementId(): string { 
            return gcfg.ADUnitId; 
    }

    /**
     * 创建新视频实例，内部方法，在视频播放完成后会再做一个新视频的缓存
     */
    private static createRewardedAd() {
        cc.log("start createRewardedAd: " + AdsManager.getRewardedPlacementId());
        if (typeof FBInstant === 'undefined') {
            return;
        }

        if (AdsManager.loadingRewardedVideoState !== LoadRewardState.none) {
            return;//只接受新创建调用，否则会引起太多个实例调用问题
        }

        { 
            
            if (AdsManager.IsSupportRewardedVideoAd) {
                //
                // Preload Rewarded
                //
                FBInstant.getRewardedVideoAsync(
                    AdsManager.getRewardedPlacementId(), // Your Ad Placement Id
                ).then(function (rewarded) {
                    // Load the Ad asynchronously
                    AdsManager.preloadedRewardedVideo = rewarded;
                    AdsManager.loadingRewardedVideoState = LoadRewardState.loading;
                    return AdsManager.preloadedRewardedVideo.loadAsync();
                }).then(function () {
                    AdsManager.loadingRewardedVideoState = LoadRewardState.load_comlepte
                    cc.log("Rewarded video preloaded.")
                }).catch(function (err) {
                    AdsManager.loadingRewardedVideoState = LoadRewardState.load_error;
                    cc.log('Rewarded video failed to preload:' + err.message);
                });

            } else {
                cc.log('Ads not supported in this session');
            }
        }
    }

    /**
     * 加载视频广告
     *  在需要加载广告的点，添加相应方法，以缓存视频备用
     */
    public static loadRewardedVideo() {
        cc.log("start loadRewardedVideo: " + AdsManager.getRewardedPlacementId());
        if (typeof FBInstant === 'undefined') {
            return;
        }

        if (AdsManager.loadingRewardedVideoState === LoadRewardState.load_comlepte ||
            AdsManager.loadingRewardedVideoState === LoadRewardState.loading) {
            return;//如果正在加载，或加载成功则返回，重复加载会引起错误
        }

        if (AdsManager.preloadedRewardedVideo) {//已经存在视频实例则去服务器加载
            cc.log("preloadedRewardedVideo start loadAsync.")
            AdsManager.loadingRewardedVideoState = LoadRewardState.loading;
            AdsManager.preloadedRewardedVideo.loadAsync().then(function () {
                cc.log("loadRewardedVideo video preloaded.")
                AdsManager.loadingRewardedVideoState = LoadRewardState.load_comlepte;
            }).catch(function (err) {
                AdsManager.loadingRewardedVideoState = LoadRewardState.load_error;
                cc.log('loadRewardedVideo video failed to preload:' + err.message);
            });
        } else {//如果实例不存在，则去创建一个新视频实例
            AdsManager.createRewardedAd();
        }
    }

    /**
     * 展示激励视频
     * @param callback 展示成功回调
     * @param err 展示出错回调
     */
    public static showRewardedVideo(callback, err) {
        cc.log("start showRewardedVideo: " + AdsManager.getRewardedPlacementId());
        if (typeof FBInstant === 'undefined') {
            err && err();
            return;
        }

        if (AdsManager.loadingRewardedVideoState !== LoadRewardState.load_comlepte) {
            cc.log("showRewardedVideo: not load.. try loading ... ");
            err && err();
            AdsManager.loadRewardedVideo();
            return;//如果在加载则不重新调用加载，否则FB会引起 正在 load() 中的错误
        }

        AdsManager.preloadedRewardedVideo.showAsync()
            .then(function (res) {
                // Perform post-ad success operation
                cc.log("showRewardedVideo ok.",res);
                callback && callback();
                AdsManager.LastShowAdsTime = cc.sys.now() / 1000;//显示视频后记录下显示时间
                AdsManager.loadingRewardedVideoState = LoadRewardState.none;
                AdsManager.preloadedRewardedVideo = null;//播放完成需置为空，下次会创建新实例，每个实例每次播放只能使用一次
                AdsManager.loadRewardedVideo();//request next
            }).catch(function (e) {
                cc.log("showRewardedVideo error : " + e.message);
                err && err();

                AdsManager.loadRewardedVideo();//request next 播放出错需重新加载，实例保持不需释放
            });
    }

    /**
     * 判断是否有加载成功的广告，可用于是否显示相应的视频按钮
     */
    public static isCompleteVideoLoad() {
        return AdsManager.loadingRewardedVideoState === LoadRewardState.load_comlepte;
    }

    /**
     * 获取插屏广告Id
     */
    private static getInterstitialPlacementId(): string { 
        return gcfg.InterstitialADId; 
    }



    //是否支插屏广告
    public static get IsSupportInterstitialAd():boolean
    {
        let supportedAPIs: string[] = FBInstant.getSupportedAPIs();
        return supportedAPIs.indexOf('getInterstitialAdAsync') !== -1
    }

    //是否支持奖励视频广告
    public static get IsSupportRewardedVideoAd():boolean
    {
        let supportedAPIs: string[] = FBInstant.getSupportedAPIs();
        return supportedAPIs.indexOf('getRewardedVideoAsync') !== -1
    }

 

    /**
     * 创建插屏广告
     */
    private static createInterstitialAd() {
        cc.log("start createInterstitialAd: " + AdsManager.getInterstitialPlacementId());
        if (typeof FBInstant === 'undefined') {
            return;
        }

        if (AdsManager.loadingInterstitialState !== LoadInterstitialState.none) {
            return;//只接受新创建调用，否则会引起太多个实例调用问题
        }

        {
           
            if (AdsManager.IsSupportInterstitialAd) {
                //
                // Preload Rewarded
                //
                FBInstant.getInterstitialAdAsync(
                    AdsManager.getInterstitialPlacementId(), // Your Ad Placement Id
                ).then(function (interstitial) {
                    // Load the Ad asynchronously
                    AdsManager.preloadedInterstitial = interstitial;
                    AdsManager.loadingInterstitialState = LoadInterstitialState.loading;
                    return AdsManager.preloadedInterstitial.loadAsync();
                }).then(function () {
                    AdsManager.loadingInterstitialState = LoadInterstitialState.load_comlepte
                    cc.log("interstitial preloaded.")
                }).catch(function (err) {
                    AdsManager.loadingInterstitialState = LoadInterstitialState.load_error;
                    cc.log('interstitial failed to preload:' + err.message);
                });

            } else {
                cc.log('Ads not supported in this session');
            }
        }
    }

    /**
     * 加载插屏广告，可在需要需要缓存的点调用
     */
    public static loadInterstitial() {
        cc.log("start loadInterstitial: " + AdsManager.getInterstitialPlacementId());
        if (typeof FBInstant === 'undefined') {
            return;
        }

        if (AdsManager.loadingInterstitialState === LoadInterstitialState.load_comlepte ||
            AdsManager.loadingInterstitialState === LoadInterstitialState.loading) {
            return;//如果正在加载，或加载成功则返回，重复加载会引起错误
        }

        if (AdsManager.preloadedInterstitial) {//已经存在视频实例则去服务器加载
            cc.log("preloadedInterstitial start loadAsync.")
            AdsManager.loadingInterstitialState = LoadInterstitialState.loading;
            AdsManager.preloadedInterstitial.loadAsync().then(function () {
                cc.log("loadInterstitial preloaded.")
                AdsManager.loadingInterstitialState = LoadInterstitialState.load_comlepte;
            }).catch(function (err) {
                AdsManager.loadingInterstitialState = LoadInterstitialState.load_error;
                cc.log('loadInterstitial failed to preload:' + err.message);
            });
        } else {//如果实例不存在，则去创建一个新视频实例
            AdsManager.createInterstitialAd();
        }
    }

    /**
     * 展示插屏广告
     * @param callback 展示成功回调
     * @param err 展示失败回调
     */
    public static showInterstitial(callback, err) {
        cc.log("start showInterstitial: " + AdsManager.getInterstitialPlacementId());
        if (typeof FBInstant === 'undefined') {
            err && err();
            return;
        }

        if (AdsManager.loadingInterstitialState !== LoadInterstitialState.load_comlepte) {
            cc.log("showInterstitial: not load.. try loading ... ");
            err && err();
            AdsManager.loadInterstitial();
            return;//如果在加载则不重新调用加载，否则FB会引起 正在 load() 中的错误
        }

        if (AdsManager.LastShowAdsTime && cc.sys.now() / 1000 - AdsManager.LastShowAdsTime <= AdsManager.AdsCDTime) {
            cc.log("showInterstitial: too often ... " + (cc.sys.now() / 1000 - AdsManager.LastShowAdsTime));
            err && err();
            return;
        }

        AdsManager.preloadedInterstitial.showAsync()
            .then(function (res) {
                // Perform post-ad success operation
                cc.log("showInterstitial ok.",res);
                callback && callback();
                AdsManager.LastShowAdsTime = cc.sys.now() / 1000;
                AdsManager.loadingInterstitialState = LoadInterstitialState.none;
                AdsManager.preloadedInterstitial = null;//播放完成需置为空，下次会创建新实例，每个实例每次播放只能使用一次
                AdsManager.loadInterstitial();//request next
            }).catch(function (e) {
                cc.log("showInterstitial error : " + e.message);
                err && err();

                AdsManager.loadInterstitial();//request next 播放出错需重新加载，实例保持不需释放
            });
    }

    /**
     * 判断插屏广告是否加载完成
     */
    public static isCompleteInterstitialLoad() {
        let iscompleted = AdsManager.loadingInterstitialState === LoadInterstitialState.load_comlepte;
        if (!iscompleted) {
            AdsManager.loadInterstitial();
        }

        return iscompleted;
    }

    /**
     * 重置上次显示广告时间，主要用于主动请求广告前重置
     */
    public static resetLastShowAdsTime() {
        AdsManager.LastShowAdsTime = 0;
    }

    //开始自动预装插屏广告，内部自动定时重装
    public static StartAutoPreloadInterstitial()
    {
        AdsManager.loadInterstitial();
        setInterval(
            ()=>{
                AdsManager.loadInterstitial();
            },
            5000
        )
    }

     //开始自动预装视频广告，内部自动定时重装
     public static StartAutoPreloadRewardedVideo()
     {
         AdsManager.loadRewardedVideo();
         setInterval(
             ()=>{
                 AdsManager.loadRewardedVideo();
             },
             10000
         )
     }
}
